Release 10.1A: OpenEdge Development:
Progress 4GL Handbook
Looking at the main block
So far most of the code you’ve looked at has been set-up code. It is either definitions of objects and variables or triggers to execute when events happen later on.
Finally you’ve arrived at the part of the procedure that is actually executed when you run the procedure. This is the main block of the procedure. Note that main block is not a Progress 4GL syntax element or a required structure in any way. It is really just a convention observed by the Section Editor. After all the definitions and triggers, you write the executable code for the procedure itself.
The main block of an AppBuilder-generated procedure that creates a window is entirely standard. You can add more initialization code to the block if you wish, but normally you won’t want to remove what it already does. A few of these statements won’t mean a lot to you yet, but for now take a quick look at this block to see a bit more about how events are set up for a typical GUI application.
The first statement simply assigns the value for a built-in function you saw earlier, the
CURRENT-WINDOW. As the comment on the statement explains, this determines defaults for proper parenting of dialog boxes and frames to the windows with which they are associated:
The next statement is more interesting. Remember that back in the Trigger section there is a trigger on the
WINDOW-CLOSEevent, then another trigger for when the user clicks on the close button in the upper-right corner of a window. This event in turn applies theCLOSEevent to the executing procedure itself:
Now you have come to the next step in this cascading series of actions:
When the user clicks the close button in the window, a trigger applies a
CLOSEevent to the procedure. Now here in the main block is another trigger block that defines the action for thatCLOSEevent, namely to run an internal procedure calleddisable_UI. This AppBuilder-generated procedure is the counterpart ofenable_UI. It deletes theC-Winstructure that defines the window and then deletes the procedure itself.So now the AppBuilder has set up all the actions necessary to clean up when the window and the procedure that created it are no longer needed.
The next statement,
PAUSE 0 BEFORE-HIDE, sets up a standard GUI default for automatically hiding windows and frames when the user selects some other object that is on top of them.Now you get to the main block itself. The AppBuilder emphasizes this by giving the header name
MAIN-BLOCKto theDO-ENDblock, which is the heart of the procedure:
The qualifiers on the
DOstatement aren’t important for now. They simply assure that on an error, a cancel, or an escape request from the user, the block terminates. You’ll learn more about undoing blocks in Chapter 17, " Managing Transactions."The first action the block takes is to run the internal procedure
enable_UI. You’ve seen thatenable_UIopens the queries, gets a Customer, displays it and its Orders, and enables all the fields. Remember thatenable_UIdoesn’t have to create the window because one of the few executable statements in all the code you looked through before you got to the main block was theCREATE WINDOWstatement. So that has already happened before this point in the code.Don’t worry about the meaning of
THIS-PROCEDURE:PERSISTENTjust yet. This condition isn’t true for this window when you run it by itself, as you’re doing. So Progress executes the statementWAIT-FOR CLOSE OF THIS-PROCEDURE.The
WAIT-FORstatement is the crux of any event-driven application. A standard procedure in an older application, or any procedure that simply performs a task and then returns to its caller, proceeds through its list of statements and then ends. When Progress gets to the final executable statement in a procedure like that, it automatically destroys the procedure (giving back the memory its variables used) and returns to the caller.But in our event-driven procedure, all that really has happened when this last statement is reached is to create a window, set up a few triggers, open two queries, display a record and a browse, and enable some fields. If the procedure were to terminate as soon as that was done, the user would have no chance to interact with the window.
![]()
To experiment and see what happens with and without the
WAIT-FORstatement:
- Highlight the two-line statement with the
WAIT-FORkeyword in it:
![]()
- From the AppBuilder menu, select Edit
Format Selection
Comment.
This option puts comment markers around the text you selected. The Comment and Indent options are a handy way to try things out with and without bits of code you’re testing.
- Click the Save button or select File
Save from the menu to save
h-CustOrderWin1.wback to the operating system.Now comes the tricky part. If you simply run the window procedure now from the AppBuilder, it works perfectly well. That is, the window comes up and stays up until the user closes it. How come? The AppBuilder is smart enough to realize that whenever you run any procedure that has a window, it has to persist so that the user can interact with it. So it effectively adds a
WAIT-FORstatement for you for testing purposes.
![]()
To see the actual effect of your change in a run-time environment:
The test window flashes almost imperceptibly and then disappears. All the initialization actions happen but then the procedure terminates. That’s why you need the
WAIT-FOR.
![]()
To correct this code:
Now the window comes up and stays up, waiting for the events that fire its trigger code, as you click buttons, and then finally the close event that terminates the procedures and destroys the window.
This exercise illustrates why you have to tell Progress not to terminate the procedure until the user is done with it. This is what the
WAIT-FORstatement does. And when you write aWAIT-FORstatement, you have to tell Progress to wait for some particular event, because otherwise the procedure would never end.So the statement says to wait for the
CLOSEevent on the procedure. And when will this happen? It will be when the user closes the window, as you’ve seen. So at that point the main block ends, theCLOSEtrigger fires, which executes thedisable_UIcode to clean up the resources the procedure and the window use, and everything goes away.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |